
import ioml
import ioelement

class OK(object):
    """env=None,requestid=None,path=None,status='OK',time='0.0',bodyelement=None,element=None"""
    def __init__(self,env=None,requestid=None,path=None,status='OK',time='0.0',bodyelement=None,element=None):
        self.requestid=requestid
        self.status = status
        self.path = path
        self.time = time
        
        if element is not None:
            self._from_element(element)
        
        self.header = ioelement.IOElement(self.requestid,{'type':'responses.' + self.status,'path':self.path,'time':self.time})
        self.bodyelement = bodyelement
        if bodyelement is None:
            self.string = ''.join(('<ioml v="',ioml.VERSION,'">','<h>',self.header.to_string(env=env),'</h>','<b />','</ioml>'))
        else:
            self.string = ''.join(('<ioml v="',ioml.VERSION,'">','<h>',self.header.to_string(env=env),'</h>','<b>',bodyelement.to_string(env=env),'</b></ioml>'))
    
    def _from_element(self,element):
        try:
            self.requestid = element.name
            self.path = element.attribs['path']
            self.totaltime = element.attribs['time']
        except:
            raise AttributeError, 'Invalid Response Element'
        
    def __repr__(self):
        return self.string
    
    def __str__(self):
        return self.string
    
    def to_string(self):
        return self.string

class PartialContent(OK):
    """env=None,requestid=None,path=None,status='PartialContent',time=None,bodyelement=None,element=None"""
    def __init__(self,env=None,requestid=None,path=None,status='PartialContent',time='0.0',bodyelement=None,element=None):
        OK.__init__(self,env=env,requestid=requestid,path=path,status=status,time=time,bodyelement=bodyelement,element=element)

class Mixed(object):
    """requestid=None,path=None,status='Mixed',time=None,response=None,request=None"""
    """
    <ioml version="1.0">
    <h>
        <i n="RequestID" type="responses.Mixed" path="/originalpath/" />
    <b>
        <i n="MixedResults">
            <i n="Response">
                <i n="h">
                    <i n="RequestID" type="responses.OK" path="....." />
                </i>
                <i n="b">
                    <i n="BodyData" />
                </i>
            </i>
                
            <i n="Request">
                <i n="h">
                    <i n="Request" type="requests.Add" ... />
                </i>
                <i n="b">
                    <i n="BodyData" />
                </i>
            </i>
        </i>
    </b>
</ioml>
    """
    def __init__(self,requestid=None,path=None,status='Mixed',time=None,response=None,request=None):
        self.requestid = requestid
        self.status = status
        self.path = path
        self.time = time
        
        self.request = request
        self.response = response
        
        header = ioelement.IOElement(self.requestid,{'type':self.status,'path':self.path,'time':self.time})
        
        body = ioelement.IOElement('MixedResults',{})
        responseelement = ioelement.IOElement('Response',{})
        responsehead = ioelement.IOElement('h',{})
        responsehead.add(ioelement.IOElement(self.requestid,self.response.headelement.attribs))
        responsebody = ioelement.IOElement('b',{})
            
        responseelement.add(responsehead)
        if response.bodyelement is not None:
            responsebody.add(response.bodyelement)
        responseelement.add(responsebody)
        
        requestelement = ioelement.IOElement('Request',{})
        requesthead = ioelement.IOElement('h',{})
        requesthead.add(ioelement.IOElement('Request',self.request.headelement.attribs))
        requestbody = ioelement.IOElement('b',{})
        
        requestelement.add(requesthead)
        if request.bodyelement is not None:
            requestbody.add(request.bodyelement)
        requestelement.add(requestbody)
        
        body.add(responseelement)
        body.add(requestelement)
        self.string = str(ioml.IOML(headelement=header,bodyelement=body))
        
    def __repr__(self):
        return str(self)
    
    def __str__(self):
        return self.string
       
class Response(object):
    
    def __init__(self,requestid=None,status=None,path=None,element=None):
        self.requestid=requestid
        if self.requestid is None:
            self.requestid = str(id(self))
        self.status = status
        self.path = path
        
        if element is not None:
            self._from_element(element)

        self.header = ioelement.IOElement(self.requestid,{'type':'responses.' + self.status,'path':self.path})
        
        self.string = ''.join(('<ioml v="',ioml.VERSION,'">','<h>',self.header.to_string(),'</h>','<b />','</ioml>'))

    def _from_element(self,element):
        try:
            self.requestid = element.name
            self.path = element.attribs['path']
        except:
            raise AttributeError, 'Invalid Response Element'
              
    def __repr__(self):
        return self.string
    
    def __str__(self):
        return self.string
    
    def to_string(self):
        return self.string
            
class Authorized(Response):
    
    def __init__(self,requestid=None,path=None,element=None):
        Response.__init__(self,requestid=requestid,status='Authorized',path=path,element=element)
    
class Accepted(Response):
    
    def __init__(self,requestid=None,path=None,handler=None):
        Response.__init__(self,requestid=requestid,status='Accepted',path=path)
        self.handler = handler
                   
class Redirect(Response):
    
    def __init__(self,requestid=None,path=None,newpath=None,element=None):
        self.requestid=requestid
        self.status = 'Redirect'
        self.path = path 
        self.newpath = newpath
        
        if element is not None:
            self._from_element(element)
        
        self.header = ioelement.IOElement(self.requestid,{'type':'responses.' + self.status,'path':self.path,'newpath':self.newpath})
        
        self.string = ''.join(('<ioml v="',ioml.VERSION,'">','<h>',self.header.to_string(),'</h>','<b />','</ioml>'))  

    def _from_element(self,element):
        try:
            self.requestid = element.name
            self.path = element.attribs['path']
            self.newpath = element.attribs['newpath']
        except:
            raise AttributeError, 'Invalid Response Element'

class ErrorResponse(Response):
    pass

class Unauthorized(ErrorResponse):
    """requestid=None,path=None,element=None"""
    def __init__(self,requestid=None,path=None,element=None):
        Response.__init__(self,requestid=requestid,status='Unauthorized',path=path,element=element)
           
class NotFound(ErrorResponse):
    """requestid=None,path=None,element=None"""
    def __init__(self,requestid=None,path=None,element=None):        
        Response.__init__(self,requestid=requestid,status='NotFound',path=path,element=element)       
           
class InternalError(ErrorResponse):
    """requestid=None,path=None,status='InternalError',err=None,element=None"""
    def __init__(self,requestid=None,path=None,status='InternalError',err=None,element=None):        
        self.requestid=requestid
        self.status = status
        self.path = path
        self.err = err
        
        if element is not None:
            self._from_element(element)
        
        self.header = ioelement.IOElement(self.requestid,{'type':'responses.' + self.status,'path':self.path,'err':self.err})
        
        self.string = ''.join(('<ioml v="',ioml.VERSION,'">','<h>',self.header.to_string(),'</h>','<b />','</ioml>'))  
    
    def _from_element(self,element):
        try:
            self.requestid = element.name
            self.path = element.attribs['path']
            self.err = element.attribs['err']
        except:
            raise AttributeError, 'Invalid Response Element'
        
    def __repr__(self):
        return self.string
    
    def __str__(self):
        return self.string
    
    def to_string(self):
        return self.string
    
class Forbidden(InternalError):
    """requestid=None,path=None,err=None,element=None"""
    def __init__(self,requestid=None,path=None,err=None,element=None):
        InternalError.__init__(self,requestid=requestid,status='Forbidden',path=path,err=err,element=element)
        
if __name__ == '__main__':
    pass
#    #from coffeetalk.utilities import environment
#    from coffeetalk.protocol import iotypes
#    import requests
#    
#    env= iotypes.Environment('0.0.0.0','joe','schmoe','conn_id','1020')
#    
#    add = requests.Add(requesitd='Mike',path='/System/Foo/Bar/',iobject=ioelement.IOElement('Buzz',{}))
#    ok = OK(env=env,requestid='Mike',path='/System/Foo/Bar1/',time='0.001',bodyelement=ioelement.IOElement('This is some content!',{}))
#    mixed = Mixed(requestid='Mike',path='/System/Foo/Add/',time='5.0',response=ioml.IOML(iomlstring=str(ok)),request=ioml.IOML(iomlstring=str(add)))
#    
#    mixedstring = str(mixed)
#    print mixedstring
#    
#    import zlib
#    
#    compressed = zlib.compress(mixedstring)
#    
#    print len(mixedstring)
#    print len(compressed)
#    
#    